package cn.achao.csr.system.controller;

import cn.achao.csr.api.SequenceApi;
import cn.achao.csr.base.constant.SecurityConstants;
import cn.achao.csr.log.annotation.CsrLog;
import cn.achao.csr.log.enums.BusinessType;
import cn.achao.csr.log.enums.OperatorType;
import cn.achao.csr.redis.service.RedisService;
import cn.achao.csr.system.service.TestService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 测试控制层
 * @Author: achao
 **/
@Slf4j
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
public class SysTestController {


    private final SequenceApi sequenceApi;
    private final RedisService redisService;
    private final ThreadPoolTaskExecutor threadPoolExecutor;

    @Autowired
    @Qualifier("TestServiceImpl")
    private TestService testService;

    @Autowired
    @Qualifier("TestAsyncServiceImpl")
    private TestService testAsyncService;

    /**
     * 获取美团分布式Id
     * @return
     */
    @GetMapping("/getIdTest")
    public Long getId() {
        Long id = sequenceApi.getSegmentId("leaf-segment-test", SecurityConstants.INNER);
        return id;
    }


    /**
     * 缓存测试
     * @param key
     * @return
     */
    @GetMapping("/redisTest/{key}")
    public String redisTest(@PathVariable String key) {
        redisService.setCacheObject(key, "hello redis", 10L, TimeUnit.SECONDS);
        return redisService.getCacheObject(key);
    }

    /**
     * 项目线程池测试
     * @return
     */
    @GetMapping("/threadTest")
    public String threadTest(boolean flag) throws ExecutionException, InterruptedException {
        Long sleep = 3000L;
        if (flag) {
            // 线程方式一
            Future<String> goHome = testAsyncService.goHome(sleep);
            log.info("异步 等待中【有效】....");
            String home = goHome.get();
            log.info("异步 等待中【有效】....{}", home);
            testAsyncService.playGame();
            testAsyncService.sleep(sleep);

            // 线程方式二
            threadPoolExecutor.execute(() -> {
                testService.sleep(sleep);
                log.info("线程方式二 线程1...");
            });
            threadPoolExecutor.execute(() -> log.info("线程方式二 线程2..."));

            // 线程方式三
            CompletableFuture.runAsync(() -> log.info("线程方式三 线程1..."), threadPoolExecutor);
        } else {
            Future<String> goHome = testService.goHome(sleep);
            log.info("非异步 等待中【无效】....");
            String home = goHome.get();
            log.info("非异步 等待中【无效】....{}", home);
            testService.playGame();
            testService.sleep(sleep);
        }


        return "hello thread";
    }


    @GetMapping("/logTest")
    @CsrLog(title = "记录日志", businessType = BusinessType.OTHER, operatorType = OperatorType.OTHER, excludeParamNames = {"exclude"})
    public String logTest(String key, String exclude) {
        return "记录日志成功";
    }
}
